// utils/request.js
// ==================== 配置区域 ====================
const BASE_URL = 'https://dev.xlhw.cc' // 基础接口地址
const TIMEOUT = 15000 // 请求超时时间
const LOG_ENABLED = true // 是否启用请求日志
const SENSITIVE_KEYS = ['token', 'authorization', 'password'] // 敏感字段过滤
// ==================== 核心请求器 ====================



let isRefreshing = false // Token刷新锁定
let requestsQueue = [] // 请求重试队列
// 基础请求方法
function createRequest(method) {
  return async (url, data, config = {}) => {
    // 合并配置
    const { 
      headers = {},
      loading = false,
      autoRetry = true,
      ...restConfig 
    } = config
    // 请求ID生成
    const requestId = Date.now().toString(36) + Math.random().toString(36).substr(2)
    
    try {
      // 显示加载状态
      if (loading) uni.showLoading({ title: '加载中...', mask: true })
      // 获取最新Token
      let token = uni.getStorageSync('token')
      const refreshToken = uni.getStorageSync('refreshToken')
      // 请求拦截器
      const requestConfig = {
        url: BASE_URL + url,
        method: method.toUpperCase(),
        data,
        header: {
          'Content-Type': 'application/json',
          Authorization: token ? `Bearer ${token}` : '',
          ...headers
        },
        timeout: TIMEOUT,
        ...restConfig
      }
      // 记录请求日志
      logRequest({
        id: requestId,
        config: requestConfig,
        timestamp: Date.now()
      })
      // 发送请求
      const response = await uniRequest(requestConfig)
      // 响应拦截器
      if (response.statusCode === 401 && autoRetry) {
        if (!isRefreshing) {
          isRefreshing = true
          try {
            // 刷新Token
            const newTokens = await refreshToken(refreshToken)
            uni.setStorageSync('token', newTokens.token)
            uni.setStorageSync('refreshToken', newTokens.refreshToken)
            
            // 重试队列中的请求
            requestsQueue.forEach(cb => cb(newTokens.token))
            requestsQueue = []
            
            // 重试当前请求
            return createRequest(method)(url, data, config)
          } catch (refreshError) {
            // Token刷新失败处理
            handleAuthError()
            throw refreshError
          } finally {
            isRefreshing = false
          }
        } else {
          // 将请求加入重试队列
          return new Promise(resolve => {
            requestsQueue.push(newToken => {
              resolve(createRequest(method)(url, data, {
                ...config,
                headers: { ...headers, Authorization: `Bearer ${newToken}` }
              }))
            })
          })
        }
      }
      // 记录响应日志
      logResponse({
        id: requestId,
        config: requestConfig,
        response,
        timestamp: Date.now()
      })
      return handleResponse(response)
    } catch (error) {
      // 错误处理
      logError({
        id: requestId,
        error,
        timestamp: Date.now()
      })
      throw handleError(error)
    } finally {
      if (loading) uni.hideLoading()
    }
  }

}
// ==================== 工具方法 ====================
// 封装uni.request为Promise
function uniRequest(config) {
  return new Promise((resolve, reject) => {
    uni.request({
      ...config,
      success: res => resolve(res),
      fail: err => reject(err)
    })
  })
}
// Token刷新方法
async function refreshToken(refreshToken) {
  const response = await uniRequest({
    url: BASE_URL + '/auth/refresh',
    method: 'POST',
    data: { refreshToken }
  })
  return response.data
}
// ==================== 日志系统 ====================
function logRequest({ id, config, timestamp }) {
  if (!LOG_ENABLED) return
  
  console.groupCollapsed(`%c[Request] ${config.method} ${config.url}`, 'color: #888')
  console.log('Request ID:', id)
  console.log('Time:', new Date(timestamp).toLocaleTimeString())
  console.log('Headers:', maskSensitive(config.header))
  console.log('Data:', maskSensitive(config.data))
  console.groupEnd()
}
function logResponse({ id, config, response, timestamp }) {
  if (!LOG_ENABLED) return
  
  console.groupCollapsed(`%c[Response] ${config.method} ${config.url} ➔ ${response.statusCode}`, 
    `color: ${response.statusCode >= 400 ? '#ff4444' : '#4CAF50'}`
  )
  console.log('Request ID:', id)
  console.log('Status:', response.statusCode)
  console.log('Duration:', `${Date.now() - timestamp}ms`)
  console.log('Data:', maskSensitive(response.data))
  console.groupEnd()
}
function logError({ id, error, timestamp }) {
  if (!LOG_ENABLED) return
  
  console.groupCollapsed(`%c[Error] ${error.errMsg || error.message}`, 'color: #ff4444')
  console.log('Request ID:', id)
  console.log('Time:', new Date(timestamp).toLocaleTimeString())
  console.error(error)
  console.groupEnd()
}
// 敏感信息脱敏
function maskSensitive(obj) {
  return JSON.parse(JSON.stringify(obj, (key, value) => {
    return SENSITIVE_KEYS.includes(key.toLowerCase()) ? '***' : value
  }))
}
// ==================== 错误处理 ====================
function handleResponse(response) {
  if (response.statusCode >= 200 && response.statusCode < 300) {
    return response.data
  }
  
  const error = new Error(response.data?.message || `请求失败 (${response.statusCode})`)
  error.code = response.statusCode
  throw error
}
function handleError(error) {
  const errorMessage = error.errMsg || error.message
  uni.showToast({
    title: errorMessage.includes('Network Error') ? '网络连接异常' : errorMessage,
    icon: 'none'
  })
  return error
}
function handleAuthError() {
  uni.showModal({
    title: '提示',
    content: '登录状态已过期，请重新登录',
    showCancel: false,
    success() {
      uni.reLaunch({ url: '/pages/login' })
    }
  })
}
// ==================== 暴露接口 ====================
export const request = {
  get: createRequest('GET'),
  post: createRequest('POST'),
  put: createRequest('PUT'),
  delete: createRequest('DELETE')
}
